﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using Cofe.Core.Filter;

namespace Cofe.Core.Utils
{
    public static class PathUtils
    {

        public static ParsableType DetectParseType(string path)
        {
            if (String.IsNullOrEmpty(path))
                return ParsableType.ParsePath;
            
            if (Regex.Match(path, RegexPatterns.FileSystemGuidPattern).Success)
                return ParsableType.Guid;

            if (path.StartsWith("{"))
                return ParsableType.ParsePath;

            return ParsableType.FilterString;
        }


        public static bool IsDirectoryListerRoot(string parseName)
        {
            Match match = Regex.Match(parseName, RegexPatterns.ParseDirectoryListerLink);
            if (match.Success)
                return String.IsNullOrEmpty(match.Groups["path"].Value);
            return false;
        }

        #region Conversion - Slash
        /// <summary>
        /// Add a slash "\" to end of input if not exists.
        /// </summary>
        public static string AppendSlash(string input)
        {
            if (input.EndsWith(@"\")) { return input; }
            else
            { return input + @"\"; }
        }

        /// <summary>
        /// Add a slash "\" to front of input if not exists.
        /// </summary>
        public static string AppendFrontSlash(string input)
        {
            if (input.StartsWith(@"\")) { return input; }
            else
            { return @"\" + input; }
        }

        /// <summary>
        /// Remove a slash "\" from the front of input if exists.
        /// </summary>		
        public static string RemoveFrontSlash(string input)
        {
            if (input.StartsWith(@"\")) { return input.Substring(1, input.Length - 1); }
            else
                if (input.StartsWith(@"/")) { return input.Substring(1, input.Length - 1); }
                else
                { return input; }
        }

        public static string Combine(string path1, string path2)
        {
            return RemoveSlash(path1) + "\\" + RemoveFrontSlash(path2);
        }

        /// <summary>
        /// Remove slash end of input.
        /// </summary>
        public static string RemoveSlash(string input)
        {
            if (input.EndsWith(@"\")) { return input.Substring(0, input.Length - 1); }
            else
            { return input; }
        }
        /// <summary>
        /// Return filename.
        /// </summary>
        public static string ExtractFileName(string input)
        {
            Int32 idx = input.LastIndexOfAny((",\\;").ToCharArray()) + 1;
            if (idx == 0)
                return input;
            return input.Substring(idx);
        }

        /// <summary>
        /// Return the first directory found from the input. 
        /// (E.g. ExtractFirstDir("\temp\1\2",0) will return "Temp")
        /// </summary>
        public static string ExtractFirstDir(string input, Int32 startIndex)
        {
            if (input.Length < startIndex)
                return "";

            Int32 idx = input.IndexOf('\\', startIndex);
            if (idx == -1)
                return input.Substring(startIndex);
            return input.Substring(startIndex, idx - startIndex);
        }

        public static string ExtractTrailDir(string input, Int32 startIndex)
        {
            string firstDir = ExtractFirstDir(input, startIndex);
            return PathUtils.RemoveFrontSlash(input.Substring(firstDir.Length + startIndex)); //FIX: 12-20-07
        }

        /// <summary>
        /// Return file path.
        /// </summary>
        public static string ExtractFilePath(string input)
        {
            if (input.Length <= 1)
                return "";
            Int32 idx = input.LastIndexOfAny((",\\;").ToCharArray()) + 1;
            if (idx == 0)
                return input;
            return input.Substring(0, idx - 1);
        }

        /// <summary>
        /// Return file extension.
        /// </summary>
        public static string ExtractFileExt(string input)
        {
            Int32 idx = input.LastIndexOfAny((",\\;.").ToCharArray());
            if ((idx > 0) && (input[idx] == '.'))
                return input.Substring(idx, input.Length - idx);
            return "";
        }

        /// <summary>
        /// Remove file extension and return the value.
        /// </summary>
        public static string RemoveFileExt(string input)
        {
            Int32 idx = input.LastIndexOfAny((",\\;.").ToCharArray());
            if ((idx > 0) && (input[idx] == '.'))
                return input.Substring(0, idx);
            return input;
        }

        /// <summary>
        /// Change file extension to specified type and return the value.
        /// </summary>
        public static string ChangeFileExt(string input, string ext)
        {
            if (!ext.StartsWith("."))
                ext = "." + ext;
            return RemoveFileExt(input) + ext;
        }

        /// <summary>
        /// Remove file drive and return the value.
        /// </summary>
        public static string RemoveFileDrive(string input)
        {
            if (input.Length >= 3) //"C:\"
            {
                if (input.IndexOf(@":\") != -1)
                {
                    return input.Substring(input.IndexOf(@":\") + 2);
                }
            }
            return "";
        }

        /// <summary>
        /// Return file drive.
        /// </summary>
        public static char GetFileDrive(string input)
        {
            if (input.Length >= 3) //"C:\"
            {
                if (input.Substring(1, 2) == @":\")
                {
                    return input[0];
                }
            }
            return ' ';
        }

        /// <summary>
        /// Return a common folder so that all files is under that common folder.
        /// (e.g. C:\1\2, C:\1\3 will return "C:\1")
        /// </summary>
        public static string HighestCommonFolder(string[] files)
        {
            if (files == null) return "";
            if (files.Length <= 0) return "";

            string retVal = PathUtils.ExtractFilePath(files[0]).ToLower();
            foreach (string item in files)
            {
                string path = PathUtils.ExtractFilePath(item).ToLower();

                if (retVal != path)
                    if (path.IndexOf(retVal) == 0)
                        retVal = path;
                    else if (retVal.IndexOf(retVal) == 0)
                    {
                        //do nothing						
                    }
                    else
                        throw new ArgumentException("Not all file based on same relative folder!");
            }

            return PathUtils.AppendSlash(retVal);
        }

        #endregion

        public static IEntryFilter[] MaskToEntryFilter(string mask, 
            params IEntryFilter[] extraFilters)
        {
            List<IEntryFilter> retVal = new List<IEntryFilter>(extraFilters);
            var fname = PathFE.GetFileName(mask);
            var fpath = PathFE.GetDirectoryName(mask);
            if (!(String.IsNullOrEmpty(fpath)))
                retVal.Add(new RootEntryFilter(fpath));
            var match = Regex.Match(fname, RegexPatterns.ParseFileNameAndExtPattern);
            if (!(String.IsNullOrEmpty(match.Groups["name"].Value)))
                retVal.Add(new FileNameEntryFilter(match.Groups["name"].Value));
            if (!(String.IsNullOrEmpty(match.Groups["ext"].Value)))
                retVal.Add(new FileTypeEntryFilter(match.Groups["ext"].Value));

            return retVal.ToArray();
        }        
       
        
         

    }
}
